package instances

import (
	"cloud_android_backend/pkg/utils"
	"fmt"
	"net/url"
	"os/exec"
	"strings"
)

type TransferTextResponse struct {
	Text string `json:"text"`
}

func TransferText(Udid string, text string, userId string) (TransferTextResponse, error) {
	var transfer TransferTextResponse
	//db, err := composite.Database.GetOrm()
	//if err != nil {
	//	return transfer, err
	//}
	//instanceModel := &resources.InstanceUses{Id: instanceUseId}
	//err = instanceModel.GetByIdWithInstanceInfo(db)
	//if err != nil {
	//	return transfer, err
	//}
	//if instanceModel.UserId != userId {
	//	return transfer, fmt.Errorf("no permission")
	//}
	//textFromPhone, _ := readPhoneClipboard(Udid)
	////return TransferTextResponse{Text: textFromPhone}, nil
	//if textFromPhone != "" {
	//	transfer.Text = textFromPhone
	//}
	err := inputViaAdbIME(Udid, text)
	if err != nil {
		return transfer, err
	}
	return transfer, nil
}

// 读取手机剪贴板内容
func readPhoneClipboard(udid string) (string, error) {
	// 使用ADB广播命令获取剪贴板内容
	cmd := exec.Command("adb", "-s", udid, "shell", "am", "broadcast", "-a", "clipper.get")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("ADB命令执行失败: %v, 输出: %s", err, string(output))
	}

	// 输出示例: Broadcast completed: result=1, data="剪贴板文本"
	outputStr := string(output)
	startIdx := strings.Index(outputStr, "data=\"")
	if startIdx == -1 {
		return "", fmt.Errorf("未在输出中找到剪贴板数据: %s", outputStr)
	}
	startIdx += len("data=\"")
	endIdx := strings.Index(outputStr[startIdx:], "\"")
	if endIdx == -1 {
		return "", fmt.Errorf("剪贴板数据格式不正确: %s", outputStr)
	}
	clipboardText := outputStr[startIdx : startIdx+endIdx]

	return clipboardText, nil
}

func transferTextToDevice(udid, text string) error {
	cmd := exec.Command("adb", "-s", udid, "shell", "input", "text", text)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("ADB命令执行失败: %v, 输出: %s", err, string(output))

	}
	fmt.Println(string(output))
	return nil
}

//	func transferTextToDevice(udid, text string) error {
//		// 将文本进行Base64编码
//		encodedText := base64.StdEncoding.EncodeToString([]byte(text))
//
//		// 创建解码并设置剪贴板的命令
//		cmdStr := fmt.Sprintf("echo '%s' | base64 -d | am broadcast -a clipper.set -e text @-", encodedText)
//		cmd := exec.Command("adb", "-s", udid, "shell", cmdStr)
//
//		output, err := cmd.CombinedOutput()
//		if err != nil {
//			return fmt.Errorf("ADB命令执行失败: %v, 输出: %s", err, string(output))
//		}
//		fmt.Println(string(output))
//		return nil
//	}
//
//	func transferTextToDevice(udid, text string) error {
//		// 将中文字符转换为Unicode转义序列
//		escapedText := convertToUnicodeEscape(text)
//
//		cmd := exec.Command("adb", "-s", udid, "shell", "input", "text", escapedText)
//		output, err := cmd.CombinedOutput()
//		if err != nil {
//			return fmt.Errorf("ADB命令执行失败: %v, 输出: %s", err, string(output))
//		}
//		fmt.Println(string(output))
//		return nil
//	}
//
// // 将中文字符转换为Unicode转义序列
//
//	func convertToUnicodeEscape(text string) string {
//		var result strings.Builder
//		for _, r := range text {
//			if r > 127 {
//				result.WriteString(fmt.Sprintf("\\u%04x", r))
//			} else {
//				result.WriteRune(r)
//			}
//		}
//		return result.String()
//	}
//
// 方法2: 使用剪贴板广播
func transferTextViaBroadcast(udid, text string) error {
	// 对长文本进行分段处理
	if len(text) > 4000 {
		return transferLongText(udid, text)
	}

	encodedText := url.QueryEscape(text)
	cmd := exec.Command("adb", "-s", udid, "shell", "am", "broadcast",
		"-a", "clipper.set",
		"--es", "text", encodedText)

	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("ADB命令执行失败: %v, 输出: %s", err, string(output))
	}
	fmt.Println("传输成功:", string(output))
	return nil
}

// 处理长文本传输
func transferLongText(udid, text string) error {
	// 将长文本分割成多个段落
	chunks := splitTextIntoChunks(text, 4000)
	for i, chunk := range chunks {
		fmt.Printf("传输第 %d/%d 段...\n", i+1, len(chunks))
		if err := transferTextViaBroadcast(udid, chunk); err != nil {
			return err
		}
	}
	return nil
}

// 将文本分割成指定大小的块
func splitTextIntoChunks(text string, chunkSize int) []string {
	var chunks []string
	runes := []rune(text)

	for i := 0; i < len(runes); i += chunkSize {
		end := i + chunkSize
		if end > len(runes) {
			end = len(runes)
		}
		chunks = append(chunks, string(runes[i:end]))
	}

	return chunks
}
func runA(cmd *exec.Cmd) (string, error) {
	out, err := cmd.CombinedOutput()
	return string(out), err
}

func inputViaAdbIME(udid, text string) error {
	// 常量
	adbIme := "com.android.adbkeyboard/.AdbIME"
	adbImePkg := "com.android.adbkeyboard"
	adbImeApkPath := "/root/ADBKeyboard.apk"
	//gboardIme := "com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME"

	// 1. 获取当前输入法
	out, err := runA(exec.Command("adb", "-s", udid, "shell", "settings", "get", "secure", "default_input_method"))
	if err != nil {
		return fmt.Errorf("获取当前输入法失败: %v, 输出: %s", err, out)
	}
	currentIme := strings.TrimSpace(out)
	fmt.Println("当前输入法:", currentIme)
	go func() {
		// 2. 检查 adbIme 是否安装
		out, err = runA(exec.Command("adb", "-s", udid, "shell", "pm", "list", "packages"))
		if err != nil {
			fmt.Println("获取当前输入法失败: %v, 输出: %s", err, out)
		}
		if !strings.Contains(out, adbImePkg) {
			fmt.Println("ADB 输入法未安装，正在安装...")
			out2, err2 := runA(exec.Command("adb", "-s", udid, "install", "-r", adbImeApkPath))
			if err2 != nil {
				fmt.Println("安装 ADB 输入法失败: %v, 输出: %s", err2, out2)
			}
			// 3. 启用 ADB 输入法

		}
	}()

	out, err = runA(exec.Command("adb", "-s", udid, "shell", "ime", "enable", adbIme))
	if err != nil {
		return fmt.Errorf("启用 ADB 输入法失败: %v, 输出: %s", err, out)
	}
	fmt.Println("已启用 ADB 输入法:" + out)
	// 4. 切换到 ADB 输入法
	out, err = runA(exec.Command("adb", "-s", udid, "shell", "ime", "set", adbIme))
	if err != nil {
		return fmt.Errorf("切换到 ADB 输入法失败: %v, 输出: %s", err, out)
	}
	//time.Sleep(300 * time.Millisecond)
	command_str := fmt.Sprintf(`adb -s %s shell am broadcast -a ADB_INPUT_TEXT --es msg "%s"`, udid, text)
	command_str = strings.Replace(command_str, "?", "\\\\?", -1)
	fmt.Println(command_str)

	//5. 输入文本 via 广播
	out, err = utils.ExecuteScriptSynchronously(command_str)

	fmt.Println("text is" + text)
	fmt.Println("输入完成" + out)

	////6. 切换回 Gboard
	//out, err = runA(exec.Command("adb", "-s", udid, "shell", "ime", "set", gboardIme))
	//if err != nil {
	//	return fmt.Errorf("切换回 Gboard 输入法失败: %v, 输出: %s", err, out)
	//}

	fmt.Println("输入完成，已切换回 Gboard")
	return nil
}
